/*
*	FILE			db.h
*	DESCRIPTION		ADO like interface to access to database
*	AUTHOR			J.Zhao
*	DATE			12/08/2010
*/

#ifndef __BAZINGA4_KOOTHRAPPALI_DB_H__
#define __BAZINGA4_KOOTHRAPPALI_DB_H__

#include "common.h"


BAZINGA4_KOOTHRAPPALI_NS_BEGIN

enum COMMAND_TYPE			{ CT_TEXT, CT_STOREPROCEDURE, CT_TABLEDIRECT, CT_BULKINSERT };
enum CONNECTION_STATE		{CS_OPEN, CS_CLOSE};
enum PARAMETER_DIRECTION	{PD_IN, PD_OUT, PD_INOUT, PD_RETURNVALUE };
enum VALUE_TYPE
{
	VT_NONE    = -1,
	VT_INTEGER =  0,
	VT_FLOAT,
	VT_INT64,
	VT_NUMERIC,
	VT_DATETIME,
	VT_STRING,
	VT_BINARY,
	VT_LOB
};


/** 	
*	lob 		
*/
class BAZINGA4_API lob 
{
public:
	virtual int BAZINGA4_CC read(void* buf, const int len) = 0;
	
protected:
	virtual ~lob(){}
};

/** 	
*	value	
*/
class BAZINGA4_API value
{
public:
	virtual bool BAZINGA4_CC is_null() const = 0;
	virtual bool BAZINGA4_CC try_int(int& v) const = 0;
	virtual bool BAZINGA4_CC try_float(double& v) const = 0;
	virtual bool BAZINGA4_CC try_int64(BAZINGA4_INT64& v) const = 0;
	virtual bool BAZINGA4_CC try_time(time_t& v) const = 0;
	virtual bool BAZINGA4_CC try_string(const char*& v) const = 0;
	virtual bool BAZINGA4_CC try_lob(lob*& v) const = 0;
	virtual VALUE_TYPE BAZINGA4_CC get_type() const = 0;
	
protected:
	virtual ~value(){}	
};

/**
*	parameter
*/
class BAZINGA4_API parameter
{
public:
	virtual bool BAZINGA4_CC set_int(const int v) = 0;
	virtual bool BAZINGA4_CC set_float(const double v)  = 0;
	virtual bool BAZINGA4_CC set_int64(const BAZINGA4_INT64 v)  = 0;
	virtual bool BAZINGA4_CC set_time(const time_t v)  = 0;
	virtual bool BAZINGA4_CC set_string(const char* v)  = 0;
	virtual bool BAZINGA4_CC set_null() =0;
	virtual bool BAZINGA4_CC get_int(int& v) const=0;
	virtual bool BAZINGA4_CC get_float(double& v) const = 0;
	virtual bool BAZINGA4_CC get_int64(BAZINGA4_INT64& v) const = 0;
	virtual bool BAZINGA4_CC get_time(time_t& v) const = 0;
	virtual bool BAZINGA4_CC get_string(const char*& v) const = 0;
	virtual bool BAZINGA4_CC is_null() const=0;
	virtual const VALUE_TYPE BAZINGA4_CC get_type() const=0;
	
protected:
	virtual ~parameter(){}
};


class BAZINGA4_API strore_procdure_parameter
{
public:

	virtual const char* BAZINGA4_CC get_name() const=0;
	virtual const VALUE_TYPE BAZINGA4_CC get_type() const=0;
	virtual const PARAMETER_DIRECTION BAZINGA4_CC get_direction() const =0;
	
protected:
	virtual ~strore_procdure_parameter(){}
};

class BAZINGA4_API parameter_collection
{
public:
	virtual parameter* BAZINGA4_CC add_int(const int v,const PARAMETER_DIRECTION d=PD_IN)=0;
	virtual parameter* BAZINGA4_CC add_float(const double v,const PARAMETER_DIRECTION d=PD_IN)=0;
	virtual parameter* BAZINGA4_CC add_int64(const BAZINGA4_INT64 v,const PARAMETER_DIRECTION d=PD_IN)=0;
	virtual parameter* BAZINGA4_CC add_time(const time_t v,const PARAMETER_DIRECTION d=PD_IN)=0;
	virtual parameter* BAZINGA4_CC add_string(const char* v,const PARAMETER_DIRECTION d=PD_IN)=0;
	virtual void BAZINGA4_CC clear()=0;
	virtual parameter* BAZINGA4_CC get_at(const int idx) const=0;
protected:
	virtual ~parameter_collection(){}
};

class BAZINGA4_API table_column
{
protected:
	~table_column(){};
public:
	virtual const char*	BAZINGA4_CC column_name() const = 0;
	virtual VALUE_TYPE	BAZINGA4_CC data_type() const = 0;
	virtual bool	BAZINGA4_CC allow_null() const = 0;
	virtual int		BAZINGA4_CC column_size() const = 0;
	virtual int		BAZINGA4_CC numeric_precision() const = 0;
	virtual int		BAZINGA4_CC numeric_scale() const = 0;
	virtual bool	BAZINGA4_CC is_key() const = 0;
};

class BAZINGA4_API table
{
public:
	virtual void	BAZINGA4_CC release() = 0;
	virtual const	table_column* BAZINGA4_CC get_column_by_pos(const int pos) const = 0;
	virtual const	table_column* BAZINGA4_CC get_column_by_name(const char* name) const = 0;
	virtual int		BAZINGA4_CC column_count() const = 0;
	virtual bool	BAZINGA4_CC is_view() const = 0;

protected:	
	virtual ~table(){}
};

class BAZINGA4_API  stored_procdure
{
public:

	virtual void	BAZINGA4_CC release() = 0;
	virtual const 	strore_procdure_parameter* BAZINGA4_CC get_parameter(const int index) const = 0;
	virtual int		BAZINGA4_CC param_count() const = 0;
	virtual bool	BAZINGA4_CC is_function() const = 0;
protected:

	virtual ~stored_procdure(){}

};



class BAZINGA4_API data_reader
{
public:

	virtual bool BAZINGA4_CC close()=0;
	virtual bool BAZINGA4_CC read()=0;
	virtual const value* BAZINGA4_CC get_value_by_pos(const int pos)const =0;
	virtual const value* BAZINGA4_CC get_value_by_name(const char* name)const =0;
	virtual const VALUE_TYPE BAZINGA4_CC get_field_type(const int i) const=0;
	virtual const int	BAZINGA4_CC get_field_count() const=0;
	virtual const char* BAZINGA4_CC get_field_name(const int i) const=0;
	virtual const int	BAZINGA4_CC get_field_pos(const char* name) const=0;
	virtual bool BAZINGA4_CC is_eof()const=0;
	virtual int BAZINGA4_CC next_set() =0;
	virtual bool BAZINGA4_CC bulk_bind(void * data,bool * is_null,int index) = 0;

protected:
	~data_reader(){}
};


class BAZINGA4_API value_collection
{
public:

	virtual bool BAZINGA4_CC set_int(int value, int index) = 0;
	virtual bool BAZINGA4_CC set_float(double value, int index) = 0;
	virtual bool BAZINGA4_CC set_string(const char* value, int index) = 0;
	virtual bool BAZINGA4_CC set_time(time_t value, int index) = 0;
	virtual bool BAZINGA4_CC set_int64(BAZINGA4_INT64 value, int index) = 0;
	virtual bool BAZINGA4_CC set_null(int index) = 0;
	virtual int	 BAZINGA4_CC count() = 0;
	virtual VALUE_TYPE BAZINGA4_CC get_type() = 0;

protected:
	virtual ~value_collection(){}
};

class BAZINGA4_API bulk_inserter()
{
public:

	virtual value_collection* BAZINGA4_CC bind(VALUE_TYPE type, int length = 0) = 0;
	virtual int	  BAZINGA4_CC execute(int count) = 0;
	virtual int	  BAZINGA4_CC get_count() = 0;
	virtual bool  BAZINGA4_CC close()=0;

protected:
	virtual ~bulk_inserter(){}
};

class BAZINGA4_API command
{
public:

	virtual void BAZINGA4_CC set_command_text(const char* text)=0;
	virtual void BAZINGA4_CC set_command_type(COMMAND_TYPE ct=CT_TEXT)=0;
	virtual void BAZINGA4_CC set_fetch_count(int count)=0;
	virtual parameter_collection* BAZINGA4_CC get_parameters() const=0;
	virtual int BAZINGA4_CC execute()=0;
	virtual data_reader* BAZINGA4_CC execute_query()=0;
	virtual bulk_inserter* BAZINGA4_CC get_bulk_inserter(const int count)=0;

protected:
	~command(){}
};


class BAZINGA4_API connection
{
public:

	virtual bool BAZINGA4_CC open(const char* dbname, const char* username, const char* password) = 0;
	virtual bool BAZINGA4_CC open(const char* conn)=0;
	virtual CONNECTION_STATE BAZINGA4_CC get_state() const=0;
	virtual bool BAZINGA4_CC close()=0;
	virtual command* BAZINGA4_CC get_command()=0;
	virtual bool BAZINGA4_CC begin() = 0;
	virtual bool BAZINGA4_CC commit() = 0;
	virtual bool BAZINGA4_CC rollback() = 0;
	virtual table* BAZINGA4_CC get_schema(const char* name, const char* owner = NULL) = 0;
	virtual stored_procedure* BAZINGA4_CC get_stored_procedure(const char* name, const char* owner = NULL) = 0;
	virtual const char* BAZINGA4_CC get_error_desp() const = 0;
	virtual const char* BAZINGA4_CC get_db_info()const=0;
	virtual int BAZINGA4_CC execute(const char* sql)=0;
	virtual data_reader* BAZINGA4_CC execute_query(const char* sql, const int fetch_count = 1000)=0;
	virtual int BAZINGA4_CC getErrorCode() const = 0;

protected:
	~connection(){};	

};


BAZINGA4_KOOTHRAPPALI_NS_END

/**
*	EXPORT C INTERFACE
*/
#ifdef DLL_EXPORT
USE_BAZINGA4_KOOTHRAPPALI_NS
extern "C"
{
	connection* BAZINGA4_CALL create_connection();
	void BAZINGA4_CALL release_connection(connection* conn);
}
#endif


#endif /*__BAZINGA4_KOOTHRAPPALI_DB_H__ */



/**   
	NOTICE 
1-	Since class has a virtual protected destructor, user can not create class instance directory. the only way to get a instance is call interface we exported.
	In this case, a protected destructor makes user can not create instance and a virtual makes it can not be create by a inherited class.
	
2-	const member function. A function can only be declared const if it doesn't modify any of its fields.

*/
